#ifndef PROTOKOL_H
#define PROTOKOL_H

#include"definicje.h"
#include<inttypes.h>
#include<stdbool.h>
#include<sys/types.h>
#include<sys/socket.h>

#define MAX_PAKIET 10000

#define OP_ACK 1
#define OP_ERR 2
#define OP_DAT 3
#define OP_CAN 4
#define OP_SET 5
#define OP_LIST 6
#define OP_GET 7
#define OP_QUIT 8
#define OP_HELLO 9
#define OP_CERT 10
#define OP_KEY 11

#define poprawnaOperacja(x) ((x)==OP_ACK || (x)==OP_ERR || (x)==OP_DAT || (x)==OP_CAN || (x)==OP_SET || (x)==OP_LIST || (x)==OP_GET || (x)==OP_QUIT || (x)==OP_HELLO || (x)==OP_CERT || (x)==OP_KEY)

#define rozmiarNaglowka 12
struct naglowek
{
   uint16_t rozmiar; // rozmiar danych
   uint8_t operacja; // identyfikator operacji
   uint8_t opcje; // dodatkowe opcje
   uint32_t ktory; // ktory blok
   uint32_t suma; // suma kontrolna
};

#define rozmiarACK 16
struct pakietACK
{
   struct naglowek naglowek;
   uint32_t ktory;
};

#define rozmiarERR 16
struct pakietERR
{
   struct naglowek naglowek;
   uint32_t ktory;
};

#define rozmiarSET 14
struct pakietSET
{
   struct naglowek naglowek;
   uint16_t rozmiar;
};

#define rozmiarCERT 512
struct pakietCERT
{
   struct naglowek naglowek;
   uint8_t certyfikat[500];
};

#define rozmiarKEY 140
struct pakietKEY
{
   struct naglowek naglowek;
   uint8_t klucz[128];
};

void obliczsume(uint8_t *d);
bool czypoprawny(uint8_t *d);

int wyslijpakiet(
      const int gniazdo,
      const struct sockaddr_storage * const adres,
      uint8_t * const d,
      uint8_t * klucz,
      bool szyfrowane
      );

int odbierzpakiet(
      const int gniazdo,
      struct sockaddr_storage * const adres,
      uint8_t * const d,
      uint8_t * klucz,
    bool szyfrowane
      );

int wyslijzpotw(
      const int gniazdo,
      const struct sockaddr_storage * const adres,
      uint8_t * const d,
      uint8_t * const dp,
      uint32_t * const ktory,
      uint32_t * const ktoryp,
      uint8_t * klucz,
    bool szyfrowane
      );

int odbierzzpotw(
      const int gniazdo,
      struct sockaddr_storage * const adres,
      uint8_t * const d,
      uint32_t * const ktory,
      uint32_t * const ktoryp,
      uint8_t * klucz,
    bool szyfrowane
      );

void szyfruj(uint8_t * wejscie, uint8_t * wyjscie, uint8_t klucz);

void deszyfruj(uint8_t * wejscie, uint8_t * wyjscie, uint8_t klucz);

void piszsyslog(char tekst[], bool klient);

#endif
